#include <stdio.h>
#include <stdint.h>

union uint_double
{
	unsigned long i;
	double f;
};

float calculate_machine_epsilon(double start)
{
	union uint_double v;

	v.f = start;
	v.i++;

	return v.f - start;
}

int main()
{
	printf("%g\n", calculate_machine_epsilon(1.0));

	return 0;
}

#if 0
/*
 * intel
 */
0000000000001149 <calculate_machine_epsilon>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	f2 0f 11 45 e8       	movsd  %xmm0,-0x18(%rbp)	// (rbp-0x18)=0x3ff0000000000000
    1156:	f2 0f 10 45 e8       	movsd  -0x18(%rbp),%xmm0	// xmm0=0x3ff0000000000000
    115b:	f2 0f 11 45 f8       	movsd  %xmm0,-0x8(%rbp)		// (rbp-0x8)=0x3ff0000000000000
    1160:	48 8b 45 f8          	mov    -0x8(%rbp),%rax		// rax=0x3ff0000000000000
    1164:	48 83 c0 01          	add    $0x1,%rax			// rax=0x3ff0000000000001
    1168:	48 89 45 f8          	mov    %rax,-0x8(%rbp)		// (rbp-0x8)=0x3ff0000000000001
    116c:	f2 0f 10 45 f8       	movsd  -0x8(%rbp),%xmm0		// xmm0=0x3ff0000000000001
    1171:	f2 0f 5c 45 e8       	subsd  -0x18(%rbp),%xmm0	// xmm0=0x3cb0000000000000
    1176:	f2 0f 5a c0          	cvtsd2ss %xmm0,%xmm0		// xmm0=0x3cb0000025800000
    117a:	5d                   	pop    %rbp
    117b:	c3                   	retq   

000000000000117c <main>:
    117c:	f3 0f 1e fa          	endbr64 
    1180:	55                   	push   %rbp
    1181:	48 89 e5             	mov    %rsp,%rbp
    1184:	48 8b 05 85 0e 00 00 	mov    0xe85(%rip),%rax        # 2010 <_IO_stdin_used+0x10>	rax=0x3ff0000000000000
    118b:	66 48 0f 6e c0       	movq   %rax,%xmm0			// xmm0=0x3ff0000000000000	v4_int32 =  0x3ff00000
    1190:	e8 b4 ff ff ff       	callq  1149 <calculate_machine_epsilon>
    1195:	f3 0f 5a c0          	cvtss2sd %xmm0,%xmm0		// xmm0=0x3cb0000000000000
    1199:	48 8d 3d 68 0e 00 00 	lea    0xe68(%rip),%rdi        # 2008 <_IO_stdin_used+0x8>
    11a0:	b8 01 00 00 00       	mov    $0x1,%eax
    11a5:	e8 a6 fe ff ff       	callq  1050 <printf@plt>	// 2.22045e-16
    11aa:	90                   	nop
    11ab:	5d                   	pop    %rbp
    11ac:	c3                   	retq   
    11ad:	0f 1f 00             	nopl   (%rax)

/*
 * arm
 */
000000000040055c <calculate_machine_epsilon>:
  40055c:	d10083ff 	sub	sp, sp, #0x20
  400560:	fd0007e0 	str	d0, [sp, #8]
  400564:	fd4007e0 	ldr	d0, [sp, #8]
  400568:	fd000fe0 	str	d0, [sp, #24]
  40056c:	f9400fe0 	ldr	x0, [sp, #24]
  400570:	91000400 	add	x0, x0, #0x1
  400574:	f9000fe0 	str	x0, [sp, #24]
  400578:	fd400fe1 	ldr	d1, [sp, #24]
  40057c:	fd4007e0 	ldr	d0, [sp, #8]
  400580:	1e603820 	fsub	d0, d1, d0
  400584:	1e624000 	fcvt	s0, d0
  400588:	910083ff 	add	sp, sp, #0x20
  40058c:	d65f03c0 	ret

0000000000400590 <main>:
  400590:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  400594:	910003fd 	mov	x29, sp
  400598:	1e6e1000 	fmov	d0, #1.000000000000000000e+00
  40059c:	97fffff0 	bl	40055c <calculate_machine_epsilon>
  4005a0:	1e22c000 	fcvt	d0, s0
  4005a4:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005a8:	9119c000 	add	x0, x0, #0x670
  4005ac:	97ffffa9 	bl	400450 <printf@plt>
  4005b0:	d503201f 	nop
  4005b4:	a8c17bfd 	ldp	x29, x30, [sp], #16
  4005b8:	d65f03c0 	ret
  4005bc:	00000000 	.inst	0x00000000 ; undefined


#endif

